package function

import (
	"context"
	"errors"
	"flow-calc/common"
	"flow-calc/config"
	"flow-calc/core"
	"flow-calc/core/log"
	"sync"
)

/**
 *    Description: 基础函数父类
 *    Date: 2024/3/18
 */

type BaseFunction struct {
	Id        string // function的实例ID,用于flow内部不同实例对象的区分
	Config    *config.FuncConfig
	Flow      core.Flow
	connector core.Connector
	Next      core.Function // 下一个流式计算Function
	Prev      core.Function // 上一个流式计算Function
	// function 的自定义临时变量
	metaData map[string]interface{}
	// 管理metaData的读写锁
	mLock sync.RWMutex
}

// NewFunction 创建一个新的Function,flow 为当前所属的flow实例;config为当前Function的配置
func NewFunction(flow core.Flow, config *config.FuncConfig) core.Function {
	var f core.Function
	switch common.FunMode(config.FMode) {
	case common.V:
		f = NewVFunction()
	case common.S:
		f = NewSFunction()
	case common.L:
		f = NewLFunction()
	case common.C:
		f = NewCFunction()
	case common.E:
		f = NewEFunction()
	default:
		log.Logger().Error("创建Function实体类型不匹配: %v", config.FMode)
		return nil
	}
	f.CreateId() // 函数绑定随机ID
	if err := f.SetConfig(config); err != nil {
		log.Logger().Error("创建的Function实体设置绑定异常: %v", err)
		return nil
	}
	if err := f.SetFlow(flow); err != nil {
		log.Logger().Error("创建的Function实体Flow流绑定异常: %v", err)
		return nil
	}
	return f
}

// Call 回调逻辑函数执行(BaseFunction 为空实现,目的为了让其他类型的Function,如V,S,L,C,E等来继承BaseFunction进行重写此方法。)
func (base *BaseFunction) Call(ctx context.Context, flow core.Flow) error {
	return nil
}

// SetConfig 给当前Function实例配置策略
func (base *BaseFunction) SetConfig(s *config.FuncConfig) error {
	if s != nil {
		base.Config = s
	} else {
		return errors.New("FunctionConfig is nil")
	}
	return nil
}

// GetConfig 获取当前Function实例配置策略
func (base *BaseFunction) GetConfig() *config.FuncConfig {
	return base.Config
}

// SetFlow 给当前Function实例设置所依赖的Flow实例
func (base *BaseFunction) SetFlow(f core.Flow) error {
	if f != nil {
		base.Flow = f
	} else {
		return errors.New("flow is nil")
	}
	return nil
}

// GetFlow 获取当前Function实力所依赖的Flow
func (base *BaseFunction) GetFlow() core.Flow {
	return base.Flow
}

func (base *BaseFunction) AddConnector(conn core.Connector) error {
	if conn == nil {
		return errors.New("conn is nil")
	}
	base.connector = conn
	return nil
}

func (base *BaseFunction) GetConnector() core.Connector {
	return base.connector
}

// CreateId 给当前Function实例创建ID
func (base *BaseFunction) CreateId() {
	base.Id = core.KisID(common.FuncType)
}

// GetId 获取当前Function的FID
func (base *BaseFunction) GetId() string {
	return base.Id
}

// GetPrevId 获取当前Function上一个Function节点FID
func (base *BaseFunction) GetPrevId() string {
	if base.Prev != nil {
		return base.Prev.GetId()
	} else {
		// 当前节点就是首节点
		return common.FunctionIdFirstVirtual
	}
}

// GetNextId 获取当前Function下一个Function节点FID
func (base *BaseFunction) GetNextId() string {
	if base.Next != nil {
		return base.Next.GetId()
	} else {
		// 当前节点就是尾节点
		return common.FunctionIdLastVirtual
	}
}

// NextF 上一个函数
func (base *BaseFunction) NextF() core.Function {
	return base.Next
}

// PrevF 下一个函数
func (base *BaseFunction) PrevF() core.Function {
	return base.Prev
}

// SetN 设置下一层Function实例
func (base *BaseFunction) SetN(f core.Function) {
	base.Next = f
}

// SetP 设置上一层Function实例
func (base *BaseFunction) SetP(f core.Function) {
	base.Prev = f
}

// GetMetaData 获取Base函数自定义的元数据
func (base *BaseFunction) GetMetaData(key string) interface{} {
	base.mLock.RLock()
	defer base.mLock.RUnlock()
	if v, ok := base.metaData[key]; ok {
		return v
	}
	return nil
}

// SetMetaData 设置Base函数自定义的元数据
func (base *BaseFunction) SetMetaData(key string, value interface{}) {
	base.mLock.Lock()
	defer base.mLock.Unlock()
	base.metaData[key] = value
}
